/**
 *  Copyright [2011] Steffen Kämpke
 *  mailto: steffen.kaempke@pennychecker.de
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.pennychecker.example.mvp.presenter;

import com.google.inject.Inject;
import com.pennychecker.example.mvp.model.User;
import com.pennychecker.example.action.SaveUser;
import com.pennychecker.example.action.SaveUserResult;
import com.pennychecker.example.mvp.event.CloseViewEvent;
import com.pennychecker.example.mvp.event.EditUserEvent;
import com.pennychecker.example.mvp.event.EditUserEventHandler;
import com.pennychecker.example.mvp.event.NewUserEvent;
import com.pennychecker.swing.mvp.SwingDisplay;
import com.pennychecker.swing.mvp.SwingPresenter;
import com.pennychecker.swing.mvp.event.EventBus;
import com.pennychecker.swing.presenter.ext.event.ClickEvent;
import com.pennychecker.swing.presenter.ext.event.ClickHandler;
import com.pennychecker.swing.presenter.ext.event.HasClickHandlers;
import java.util.logging.Level;
import java.util.logging.Logger;
import net.customware.gwt.dispatch.client.ActionCallback;
import net.customware.gwt.dispatch.client.DispatchAsync;

/**
 *
 * @author Steffen Kämpke mailto:steffen.kaempke@pennychecker.de
 */
public final class EditUserPresenter extends SwingPresenter<EditUserPresenter.Display> {

    private final DispatchAsync dispatch;
    private User selectedUser;

    /**
     * 
     * @param display
     * @param eventBus
     * @param dispatch 
     */
    @Inject
    public EditUserPresenter(Display display, EventBus eventBus, DispatchAsync dispatch) {
        super(display, eventBus);
        this.dispatch = dispatch;
        bind();
    }

    @Override
    protected void onBind() {

        registerHandler(eventBus.addHandler(EditUserEvent.TYPE, new EditUserEventHandler() {

            public void onEditUserEvent(EditUserEvent event) {
                selectedUser = event.getUser();

                if (null == selectedUser) {
                    display.clearForm();
                } else {
                    display.setUser(selectedUser);
                }
            }
        }));

        registerHandler(display.getSaveButton().addClickHandler(new ClickHandler() {

            public void onClick(ClickEvent ce) {
                saveUser();
            }
        }));

        registerHandler(display.getCloseButton().addClickHandler(new ClickHandler() {

            public void onClick(ClickEvent ce) {
                display.clearForm();
                eventBus.fireEvent(new CloseViewEvent(display.asComponent()));
            }
        }));
    }

    @Override
    protected void onUnbind() {
    }

    public void refreshDisplay() {
    }

    public interface Display extends SwingDisplay {

        HasClickHandlers getSaveButton();

        HasClickHandlers getCloseButton();

        String getFirstname();

        String getLastName();

        public void setErrorMessage(String string);

        public void clearForm();

        public void setUser(User user);
    }

    private void saveUser() {
        assert null != display.getFirstname();
        assert null != display.getLastName();
        final String firstname = display.getFirstname();
        final String lastname = display.getLastName();

        if (firstname.isEmpty()) {
            display.setErrorMessage("Please insert the firstname.");
            return;
        }

        if (lastname.isEmpty()) {
            display.setErrorMessage("Please insert the firstname.");
            return;
        }
        final User user;

        if (null == selectedUser) {
            user = new User(firstname, lastname);
        } else {
            user = selectedUser;
            user.setFirstname(firstname);
            user.setLastname(lastname);
        }



        /**
         * Execute your command
         */
        dispatch.execute(new SaveUser(user), new ActionCallback<SaveUserResult>() {

            public void onFailure(Throwable caught) {
                display.setErrorMessage("An error occurred, please deinstall this application and reinstall your os ;-)");
                Logger.getLogger(EditUserPresenter.class.getName()).log(Level.SEVERE, "Could not save the user: {0} {1}", new Object[]{firstname, lastname});
            }

            public void onSuccess(SaveUserResult result) {
                Logger.getLogger(EditUserPresenter.class.getName()).log(Level.INFO, "User {0} {1} was saved.", new Object[]{firstname, lastname});
                eventBus.fireEvent(new NewUserEvent(result.getUser()));
                selectedUser = null;
                display.clearForm();
            }
        });
    }
}
